package jmvm.schemes;


import java.awt.Point;
import java.util.ArrayList;

import jmvm.components.*;
import jmvm.gui.GuiLabel;
import jmvm.gui.GuiLine;
import jmvm.gui.GuiScheme;


public class Fetch1 {
	
	public static IntToInt PC_H, IR1_sign_extend, IR0_3_0;
	public static IntToBools IR0Bits, IR1Bits, IR2Bits, IR3Bits;
	public static BoolsToInt IR2_IR3, IR1_IR2;
	
	public static REG PC, IR0, IR1, IR2, IR3;
	
	public static TSB PCout, PCHout, IRDAout, IRJAout, IRPOMout, IRBRout;
	
	////////////
	//////////// Grafika
	////////////
	
	public static GuiScheme gui;

	public static GuiScheme getGui() {
		return gui;
	}
	
	public static void gui() {

		GuiLine line; // Pomocna promenljiva
		gui = new GuiScheme("jmvm/jmvm/images/fetch1.png");
		
		ArrayList<ArrayList<Point>> sections;
		ArrayList<Point> points;
		
		// 
		// 
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(490,2));
		points.add(new Point(490,766));
		points.add(new Point(492,766));
		points.add(new Point(492,3));
		sections.add(points);
		line=new GuiLine(sections,Bus.IBUS());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(290,63));
		points.add(new Point(290,39));
		points.add(new Point(490,39));
		sections.add(points);
		line=new GuiLine(sections,Bus.IBUS());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(133,263));
		points.add(new Point(133,239));
		points.add(new Point(490,239));
		sections.add(points);
		line=new GuiLine(sections,Bus.IBUS());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(367,263));
		points.add(new Point(367,240));
		sections.add(points);
		line=new GuiLine(sections,Bus.IBUS());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(133,379));
		points.add(new Point(133,355));
		points.add(new Point(490,355));
		sections.add(points);
		line=new GuiLine(sections,Bus.IBUS());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(367,379));
		points.add(new Point(367,356));
		sections.add(points);
		line=new GuiLine(sections,Bus.IBUS());
		gui.addLine(line);

		//
		//
		
		// 
		// 
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(290,107));
		points.add(new Point(290,135));
		points.add(new Point(383,135));
		sections.add(points);
		line=new GuiLine(sections,PC.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(290,136));
		points.add(new Point(290,187));
		points.add(new Point(383,187));
		sections.add(points);
		line=new GuiLine(sections,PC_H.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(409,135));
		points.add(new Point(490,135));
		sections.add(points);
		line=new GuiLine(sections,PCout.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(409,187));
		points.add(new Point(490,187));
		sections.add(points);
		line=new GuiLine(sections,PCHout.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(133,306));
		points.add(new Point(133,326));
		sections.add(points);
		line=new GuiLine(sections,IR0.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(367,306));
		points.add(new Point(367,326));
		sections.add(points);
		line=new GuiLine(sections,IR1.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(133,423));
		points.add(new Point(133,436));
		sections.add(points);
		line=new GuiLine(sections,IR2.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(367,423));
		points.add(new Point(367,434));
		sections.add(points);
		line=new GuiLine(sections,IR3.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(409,492));
		points.add(new Point(490,492));
		sections.add(points);
		line=new GuiLine(sections,IRDAout.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(409,554));
		points.add(new Point(490,554));
		sections.add(points);
		line=new GuiLine(sections,IRJAout.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(409,617));
		points.add(new Point(490,617));
		sections.add(points);
		line=new GuiLine(sections,IRPOMout.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(409,679));
		points.add(new Point(490,679));
		sections.add(points);
		line=new GuiLine(sections,IRBRout.getOut(0));
		gui.addLine(line);

		//
		//
		// 
		// 
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(344,492));
		points.add(new Point(383,492));
		sections.add(points);
		line=new GuiLine(sections,IR2_IR3.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(343,554));
		points.add(new Point(383,554));
		sections.add(points);
		line=new GuiLine(sections,IR1_IR2.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(343,617));
		points.add(new Point(384,617));
		sections.add(points);
		line=new GuiLine(sections,IR1_sign_extend.getOut(0));
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(343,679));
		points.add(new Point(383,679));
		sections.add(points);
		line=new GuiLine(sections,IR0_3_0.getOut(0));
		gui.addLine(line);

		//
		//
		
		// 
		// 
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(199,75));
		points.add(new Point(207,75));
		sections.add(points);
		line=new GuiLine(sections,UpravOper.ldPC());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(199,95));
		points.add(new Point(206,95));
		sections.add(points);
		line=new GuiLine(sections,UpravOper.incPC());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(396,148));
		points.add(new Point(396,142));
		sections.add(points);
		line=new GuiLine(sections,UpravOper.PCout());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(396,199));
		points.add(new Point(396,194));
		sections.add(points);
		line=new GuiLine(sections,UpravOper.PCHout());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(43,295));
		points.add(new Point(50,295));
		sections.add(points);
		line=new GuiLine(sections,UpravOper.ldIR0());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(277,295));
		points.add(new Point(284,295));
		sections.add(points);
		line=new GuiLine(sections,UpravOper.ldIR1());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(43,411));
		points.add(new Point(50,411));
		sections.add(points);
		line=new GuiLine(sections,UpravOper.ldIR2());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(273,411));
		points.add(new Point(284,411));
		sections.add(points);
		line=new GuiLine(sections,UpravOper.ldIR3());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(396,505));
		points.add(new Point(396,498));
		sections.add(points);
		line=new GuiLine(sections,UpravOper.IRDAout());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(396,567));
		points.add(new Point(396,560));
		sections.add(points);
		line=new GuiLine(sections,UpravOper.IRJAout());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(396,630));
		points.add(new Point(396,622));
		sections.add(points);
		line=new GuiLine(sections,UpravOper.IRPOMout());
		gui.addLine(line);

		//
		//
		sections=new ArrayList<ArrayList<Point>>();
		points=new ArrayList<Point>();
		points.add(new Point(396,692));
		points.add(new Point(396,686));
		sections.add(points);
		line=new GuiLine(sections,UpravOper.IRBRout());
		gui.addLine(line);

		//
		//
		
		
		gui.addLabel(new GuiLabel(497, 406, Bus.IBUS()));
		
		gui.addLabel(new GuiLabel(264, 137, PC.getOut(0)));
		gui.addLabel(new GuiLabel(279, 200, PC_H.getOut(0)));
		gui.addLabel(new GuiLabel(130, 342, IR0.getOut(0)));
		gui.addLabel(new GuiLabel(364, 342, IR1.getOut(0)));
		gui.addLabel(new GuiLabel(130, 454, IR2.getOut(0)));
		gui.addLabel(new GuiLabel(364, 454, IR3.getOut(0)));



		
	}
	/////////////
	/////////////
	/////////////
	
	public static void init() {
	
		////
		PC_H = new IntToInt(16,8,true,false);
		IR1_sign_extend = new IntToInt(8,16,false,true);
		IR0_3_0 = new IntToInt(8,4,false,false);
		IR0Bits = new IntToBools(1,8);
		IR1Bits = new IntToBools(1,8);
		IR2Bits = new IntToBools(1,8);
		IR3Bits = new IntToBools(1,8);
		IR2_IR3 = new BoolsToInt(16,16);
		IR1_IR2 = new BoolsToInt(16,16);	
		////
		
		PC = new REG(1, "PC");
		PC.getOut(0).setIsInt();
		PC.getOut(0).setNumOfLines(16);
		//PC.initVal(256);						// IZMENJENO
		
		IR0 = new REG(1, "IR0");
		IR0.getOut(0).setIsInt();
		IR0.getOut(0).setNumOfLines(8);
		
		IR1 = new REG(1, "IR1");
		IR1.getOut(0).setIsInt();
		IR1.getOut(0).setNumOfLines(8);
		
		IR2 = new REG(1, "IR2");
		IR2.getOut(0).setIsInt();
		IR2.getOut(0).setNumOfLines(8);
		
		IR3 = new REG(1, "IR3");
		IR3.getOut(0).setIsInt();
		IR3.getOut(0).setNumOfLines(8);
		
		///// TSB PCout, PCHout, IRDAout, IRJAout, IRPOMout, IRBRout;
		
		PCout = new TSB();
		PCout.getOut(0).setNumOfLines(16);
		PCHout = new TSB();
		PCHout.getOut(0).setNumOfLines(8);
		IRDAout = new TSB();
		IRDAout.getOut(0).setNumOfLines(16);
		IRJAout = new TSB();
		IRJAout.getOut(0).setNumOfLines(16);
		IRPOMout = new TSB();
		IRPOMout.getOut(0).setNumOfLines(16);
		IRBRout = new TSB();
		IRBRout.getOut(0).setNumOfLines(4);
		
	}
	
	public static void connect(){

		///////
		PC_H.setInputPin(0, PC.getOut(0));
		IR1_sign_extend.setInputPin(0, IR1.getOut(0));
		IR0_3_0.setInputPin(0, IR0.getOut(0));
		IR0Bits.setInputPin(0, IR0.getOut(0));
		IR1Bits.setInputPin(0, IR1.getOut(0));
		IR2Bits.setInputPin(0, IR2.getOut(0));
		IR3Bits.setInputPin(0, IR3.getOut(0));
		for (int i = 0; i < 8; i++) {
			IR2_IR3.setInputPin(i, IR3Bits.getOut(i));
			IR2_IR3.setInputPin(i + 8, IR2Bits.getOut(i));
			IR1_IR2.setInputPin(i, IR2Bits.getOut(i));
			IR1_IR2.setInputPin(i + 8, IR1Bits.getOut(i));
		}
		///////
		
		PC.setInputPin(0, Bus.IBUS());
		PC.setPinInc(UpravOper.incPC());
		PC.setPinLd(UpravOper.ldPC());
		
		IR0.setInputPin(0, Bus.IBUS_L());
		IR0.setPinLd(UpravOper.ldIR0());
		
		IR1.setInputPin(0, Bus.IBUS_L());
		IR1.setPinLd(UpravOper.ldIR1());
		
		IR2.setInputPin(0, Bus.IBUS_L());
		IR2.setPinLd(UpravOper.ldIR2());
		
		IR3.setInputPin(0, Bus.IBUS_L());
		IR3.setPinLd(UpravOper.ldIR3());
		
		///////////////////////////////////
		
		PCout.setInputPin(0, PC.getOut(0));
		PCout.setCtrl(UpravOper.PCout());
		Bus.addOnIBUS(PCout.getOut(0));		
		
		PCHout.setInputPin(0, PC_H.getOut(0));
		PCHout.setCtrl(UpravOper.PCHout());
		Bus.addOnIBUS(PCHout.getOut(0));
		
		IRDAout.setInputPin(0, IR2_IR3.getOut(0));
		IRDAout.setCtrl(UpravOper.IRDAout());
		Bus.addOnIBUS(IRDAout.getOut(0));
		
		IRJAout.setInputPin(0, IR1_IR2.getOut(0));
		IRJAout.setCtrl(UpravOper.IRJAout());
		Bus.addOnIBUS(IRJAout.getOut(0));
		
		IRPOMout.setInputPin(0, IR1_sign_extend.getOut(0));
		IRPOMout.setCtrl(UpravOper.IRPOMout());
		Bus.addOnIBUS(IRPOMout.getOut(0));
		
		IRBRout.setInputPin(0, IR0_3_0.getOut(0));
		IRBRout.setCtrl(UpravOper.IRBRout());
		Bus.addOnIBUS(IRBRout.getOut(0));

	}
	
	public static Pin IR31() {
		return IR0Bits.getOut(7);
	}

	public static Pin IR30() {
		return IR0Bits.getOut(6);
	}

	public static Pin IR29() {
		return IR0Bits.getOut(5);
	}

	public static Pin IR28() {
		return IR0Bits.getOut(4);
	}

	public static Pin IR27() {
		return IR0Bits.getOut(3);
	}

	public static Pin IR26() {
		return IR0Bits.getOut(2);
	}

	public static Pin IR25() {
		return IR0Bits.getOut(1);
	}

	public static Pin IR24() {
		return IR0Bits.getOut(0);
	}

	public static Pin IR23() {
		return IR1Bits.getOut(7);
	}

	public static Pin IR22() {
		return IR1Bits.getOut(6);
	}
	
	public static Pin IR21() {
		return IR1Bits.getOut(5);
	}
	
	public static void ispisiRegistre() {
		System.out.println(" Registri:" + " PC=" + PC.getOut(0).getIntVal() + " IR0=" + IR0.getOut(0).getIntVal() +
							" IR1=" + IR1.getOut(0).getIntVal() + " IR2=" + IR2.getOut(0).getIntVal() + " IR3=" + IR3.getOut(0).getIntVal() );
	}
	
	public static void main(String[] args){
		
		/*IR1_sign_extend = new IntToInt(8,16,false,true);
		
		IR1_sign_extend.setInputPin(0, new Pin(64,8));
		IR1_sign_extend.func();
		
		System.out.println( Integer.toBinaryString(IR1_sign_extend.getOut(0).getIntVal()));*/

		Bus.init();
		Bus.connect();
		
		Fetch1.init();
		Fetch1.connect();
		
		Bus.addOnIBUS(new Pin(256,16));
		Bus.IBUS.func();
		
		PC.setPinLd(new Pin(true));
		
		LogicalComponent.CLK();
			
		//System.out.println( Integer.toBinaryString(Bus.IBUS_L().getIntVal()));
		System.out.println( Integer.toBinaryString(PC.getOut(0).getIntVal()));
		System.out.println( Integer.toBinaryString(PC_H.getOut(0).getIntVal()));
	}
}


